%macro FUNCTION 1
section .text
global _%1
_%1:
 .begin:
%endmacro


; void CPU_SaveContext( Registers * registers )
FUNCTION CPU_SaveContext
	; save new registers
	push	eax
	mov		eax, [esp + 8]
	mov		[eax +  0], ss
	mov		[eax +  4], gs
	mov		[eax +  8], fs
	mov		[eax + 12], es
	mov		[eax + 16], ds
	mov		[eax + 20], edi
	mov		[eax + 24], esi
	mov		[eax + 28], ebp
	push	ecx
	mov		ecx, esp
;	add		ecx, 18 * 4 + 3 * 4
	mov		[eax + 32], ecx ; TODO: unwind
	pop		ecx
	mov		[eax + 36], ebx
	mov		[eax + 40], edx
	mov		[eax + 44], ecx
	mov		ecx, [esp + 4] ; old eax
	mov		[eax + 48], ecx
	mov		[eax + 60], dword .begin ; TODO: unwind
;	pushd	cs
;	pop		ecx
	mov		word [eax + 64], cs
	pushf
	pop		ecx
	mov		dword [eax + 70], ecx
	pop		eax
	ret


; void CPU_ContextSwitch( Registers * registers )
FUNCTION CPU_ContextSwitch
	; load new registers
	mov			eax, [esp + 4]
	mov			ecx, dword [eax +  0]
	mov			ss, cx
	mov			ecx, dword [eax +  4]
	mov			gs, cx
	mov			ecx, dword [eax +  8]
	mov			fs, cx
	mov			ecx, dword [eax + 12]
	mov			es, cx
	mov			ecx, dword [eax + 16]
	mov			ds, cx
	mov			edi, dword [eax + 20]
	mov			esi, dword [eax + 24]
	mov			ebp, dword [eax + 28]
	mov			esp, dword [eax + 32]
	mov			ebx, dword [eax + 36]
	mov			edx, dword [eax + 40]
	mov			ecx, dword [eax + 44]
	mov			eax, dword [eax + 48]
	add			esp, 8 ; skip pasted interrupt and error?
	iret


FUNCTION IO_Delay
	mov		dx, 0x80
	in		eax, dx
	out		dx, eax
	ret
	
FUNCTION IO_In8
	mov		dx, word [esp + 4]
	xor		eax, eax
	in		al, dx
	ret
	
FUNCTION IO_In16
	mov		dx, word [esp + 4]
	xor		eax, eax
	in		ax, dx
	ret
	
FUNCTION IO_In32
	mov		dx, word [esp + 4]
	xor		eax, eax
	in		eax, dx
	ret
	
FUNCTION IO_Out8
	mov		dx, word [esp + 4]
	mov		al, byte [esp + 8]
	out		dx, al
	ret
	
FUNCTION IO_Out16
	mov		dx, word [esp + 4]
	mov		ax, word [esp + 8]
	out		dx, ax
	ret
	
FUNCTION IO_Out32
	mov		dx, word [esp + 4]
	mov		eax, dword [esp + 8]
	out		dx, eax
	ret

FUNCTION IO_OutArray8
	cld
	mov		dx, word [esp + 4]
	mov		esi, dword [esp + 8]
	mov		ecx, dword [esp + 12]
	rep
	outsb
	ret

FUNCTION IO_OutArray16
	cld
	mov		dx, word [esp + 4]
	mov		esi, dword [esp + 8]
	mov		ecx, dword [esp + 12]
	rep
	outsw
	ret

FUNCTION IO_OutArray32
	cld
	mov		dx, word [esp + 4]
	mov		esi, dword [esp + 8]
	mov		ecx, dword [esp + 12]
	rep
	outsd
	ret

